﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json;
using BCCommon;
using BCCommon.Enums;
using BCData.Common.FlowRecord;
using BCData.Common.Wallet;
using BCDto.Common.FlowRecord;
using BCDto.Common.Wallet;
using BCDto.Website.User;
using BCEntity.Common.FlowRecord;
using BCEntity.Common.Wallet;
using BCService.Common.SystemFinanceFlowRecord;
using BCService.Utils;
using BCCommon.PaymentEnums;

namespace BCService.Common.Wallet
{
    public class WalletService : IWalletService
    {
        private readonly IWalletData walletData;
        private readonly IUserFlowRecordData flowRecordData;
        private readonly ISystemFinanceFlowRecordService systemFinanceFlowRecordService;
        //private readonly IDriverData driverData;

        public WalletService(IWalletData walletData,
            IUserFlowRecordData flowRecordData,
            ISystemFinanceFlowRecordService systemFinanceFlowRecordService)
            //,
            //IDriverData driverData)
        {
            this.walletData = walletData;
            this.flowRecordData = flowRecordData;
            this.systemFinanceFlowRecordService = systemFinanceFlowRecordService;
            //this.driverData = driverData;
        }

        public int ChangeAliPayAuthInfo(long userId, string payAuthInfo)
        {
            return walletData.ChangeAliPayAuthInfo(userId, payAuthInfo);
        }

        public int ChangeWxPayAuthInfo(long userId, string payAuthInfo)
        {
            return walletData.ChangeWxPayAuthInfo(userId, payAuthInfo);
        }

        public WalletDto GetWalletByUserId(long userId, bool showPassword = false)
        {
            WalletEntity entity = walletData.GetWalletByUserId(userId);

            if (entity != null)
            {
                WalletDto Dto = entity.As<WalletDto>();
                //是否设置过支付密码
                Dto.HasPayPwd = !string.IsNullOrWhiteSpace(entity.PayPassword);
                //支付宝授权信息
                Dto.AlipayAuthInfo = string.IsNullOrWhiteSpace(entity.AlipayAuthInfo) ? null : JsonConvert.DeserializeObject(entity.AlipayAuthInfo);
                //微信支付授权信息
                Dto.WxPayAuthInfo = string.IsNullOrWhiteSpace(entity.WxPayAuthInfo) ? null : JsonConvert.DeserializeObject(entity.WxPayAuthInfo);
                if (!showPassword)
                {
                    Dto.PayPassword = null;
                }
                return Dto;
            }
            else
            {
                //钱包不存在创建
                var newEntity = new WalletEntity { UserId = userId, Balance = 0M };
                entity = walletData.Add(newEntity);
            }
            var dto = entity.As<WalletDto>();
            dto.HasPayPwd = !string.IsNullOrWhiteSpace(entity.PayPassword);
            dto.AlipayAuthInfo = string.IsNullOrWhiteSpace(entity.AlipayAuthInfo) ? null : JsonConvert.DeserializeObject(entity.AlipayAuthInfo);
            dto.WxPayAuthInfo = string.IsNullOrWhiteSpace(entity.WxPayAuthInfo) ? null : JsonConvert.DeserializeObject(entity.WxPayAuthInfo);
            return dto;
        }

        public PageableList<UserFlowRecordDto> GetCurrentDirverWalletDetails(long? userId, string orderNo, FlowType? flowType, 
            SourceFlowDirectionType? flowDirection, PaymentChannelType? payChannel, DateTime? start, DateTime? end, bool? ascending, int pageIndex, int pageSize)
        {
            var task = this.flowRecordData.GetPageableList(userId, orderNo, flowType, flowDirection, payChannel, start, end, ascending, pageIndex, pageSize);
            var result = task.GetAwaiter().GetResult();
            return new PageableList<UserFlowRecordDto>
            {
                Count = result.Item2,
                Items = result.Item1.As<IEnumerable<UserFlowRecordDto>>()
            };
        }

        /// <summary>
        /// 查看指定用户的账单明细
        /// </summary>
        /// <param name="userId">用户编号</param>
        /// <param name="ascending">升序排序</param>
        /// <param name="pageIndex">分页页码</param>
        /// <param name="pageSize">分页页数</param>
        /// <returns></returns>
        public PageableList<UserFlowRecordDto> GetFlowDetails(long? userId, bool? ascending, int pageIndex, int pageSize)
        {
            var task = this.flowRecordData.GetFlowDetails(userId, ascending, pageIndex, pageSize);
            var result = task.GetAwaiter().GetResult();
            return new PageableList<UserFlowRecordDto>
            {
                Count = result.Item2,
                Items = result.Item1.As<IEnumerable<UserFlowRecordDto>>()
            };
        }

        public WalletDto ResetPayPassword(string phone, long userId, WalletResetRequestDto walletResetRequestDto)
        {
            WalletEntity entity = this.walletData.GetWalletByUserId(userId);

            if (entity == null)
            {
                return null;
            }
            if (walletResetRequestDto.OperatingType == ResetOperatingType.Modify)
            {
                if (walletResetRequestDto.SourcePassword.SHA256(phone) != entity.PayPassword)
                {
                    throw new ArgumentException("旧密码错误");
                }
            }
            var dto = this.walletData.ResetPayPassword(userId, walletResetRequestDto.PayPassword.SHA256(phone)).As<WalletDto>();
            //是否设置过支付密码
            dto.HasPayPwd = true;
            //支付宝授权信息
            dto.AlipayAuthInfo = string.IsNullOrWhiteSpace(entity.AlipayAuthInfo) ? null : JsonConvert.DeserializeObject(entity.AlipayAuthInfo);
            //微信支付授权信息
            dto.WxPayAuthInfo = string.IsNullOrWhiteSpace(entity.WxPayAuthInfo) ? null : JsonConvert.DeserializeObject(entity.WxPayAuthInfo);
            return dto;
        }

        public WalletDto ChangePaypassword(UserDto user, WalletResetRequestDto walletResetRequestDto)
        {
            WalletEntity entity = this.walletData.GetWalletByUserId(user.UserId);

            if (entity == null)
            {
                return null;
            }

            if (walletResetRequestDto.SourcePassword.SHA256(user.Phone) != entity.PayPassword)
            {
                throw new ArgumentException("支付密码错误。");
            }
            var dto = this.walletData.ResetPayPassword(user.UserId, walletResetRequestDto.PayPassword.SHA256(user.Phone)).As<WalletDto>();
            //是否设置过支付密码
            dto.HasPayPwd = true;
            //支付宝授权信息
            dto.AlipayAuthInfo = string.IsNullOrWhiteSpace(entity.AlipayAuthInfo) ? null : JsonConvert.DeserializeObject(entity.AlipayAuthInfo);
            //微信支付授权信息
            dto.WxPayAuthInfo = string.IsNullOrWhiteSpace(entity.WxPayAuthInfo) ? null : JsonConvert.DeserializeObject(entity.WxPayAuthInfo);
            return dto;
        }

        public WalletDto BalanceRecharge(UserDto current, decimal rechargeAmount, string rechargeNo, PaymentChannelType channelType)
        {
            WalletDto wallet = GetWalletByUserId(current.UserId);
            if (wallet != null)
            {
                var result = walletData.BalanceRecharge(wallet.UserId, rechargeAmount + wallet.Balance);
                if (result == null)
                {
                    return null;
                }
                //增加余额充值流水
                UserFlowRecordEntity flowRecordEntity = new UserFlowRecordEntity
                {
                    Amount = rechargeAmount,
                    OrderNo = rechargeNo,
                    CreateTime = DateTime.Now,
                    Remark = $"余额充值+{rechargeAmount}元",
                    FlowDirection = SourceFlowDirectionType.Income,
                    FlowType = FlowType.Recharge,
                    Channel = channelType,
                    UserId = wallet.UserId,
                    UserName = current.UserName
                };
                flowRecordData.AddAsync(flowRecordEntity);
                this.systemFinanceFlowRecordService.WriteSystemFinanceFlowRecord(current.UserId, rechargeAmount, rechargeNo, SourceFlowDirectionType.Income, FlowType.Recharge, channelType);
                return wallet.As<WalletDto>();
            }
            return null;
        }

        public WalletDto UpdatePasswordErrorCount(long userId, int passwordErrorCount)
        {
            if (this.walletData.GetWalletByUserId(userId) == null)
            {
                throw new ArgumentException("用户钱包不存在");
            }

            Task<WalletEntity> walletEntityTask = this.walletData.UpdatePasswordErrorCount(userId, passwordErrorCount);
            return walletEntityTask.GetAwaiter().GetResult().As<WalletDto>();
        }

        public void ClearErrorCount()
        {
            this.walletData.ClearErrorCount();
        }

        public WalletDto Update(WalletDto walletDto)
        {
            WalletEntity walletEntity = this.walletData.Get(walletDto.WalletId);
            if (walletEntity == null)
            {
                throw new ArgumentException("用户钱包不存在");
            }
            if (walletEntity.UserId != walletDto.UserId)
            {
                throw new ArgumentException("请勿操作他人钱包");
            }
            walletEntity.Balance = walletDto.Balance;
            var entity = this.walletData.Update(walletEntity);
            return entity.As<WalletDto>();
        }

        public WalletDto FirstSetPayPassword(UserDto user, WalletRequestDto walletRequestDto)
        {
            WalletEntity walletEntity = this.walletData.GetWalletByUserId(user.UserId);
            if (walletRequestDto.WalletId != walletEntity.WalletId)
            {
                throw new ArgumentException("钱包信息不正确");
            }
            if (!string.IsNullOrWhiteSpace(walletEntity.PayPassword))
            {
                throw new ArgumentException("已设置支付密码,无需重复设置");
            }
            walletEntity = this.walletData.ResetPayPassword(user.UserId, walletRequestDto.PayPassword.SHA256(user.Phone));
            walletEntity.PayPassword = string.Empty;
            return walletEntity.As<WalletDto>();
        }
        
        //public PageableList<UserFlowRecordDto> UserFlowRecord(long driverId, DateTime? start, DateTime? end, bool? ascending, int index, int size)
        //{
        //    var driverEntity = this.driverData.GetDriverByDriverId(driverId);
        //    if (driverEntity == null)
        //    {
        //        throw new ArgumentException("司机信息不存在");
        //    }
        //    var task = this.flowRecordData.GetFlowDetails(driverEntity.UserId, start, end, ascending, index, size);
        //    var result = task.GetAwaiter().GetResult();
        //    return new PageableList<UserFlowRecordDto>
        //    {
        //        Count = result.Item2,
        //        Items = result.Item1.As<IEnumerable<UserFlowRecordDto>>()
        //    };
        //}

        //public WalletDto GetWalletByDriverId(long driverId)
        //{
        //    var driverEntity = this.driverData.GetDriverByDriverId(driverId);
        //    if (driverEntity == null)
        //    {
        //        throw new ArgumentException("司机信息不存在");
        //    }
        //    return this.walletData.GetWalletByUserId(driverEntity.UserId).As<WalletDto>();
        //}
    }
}
